<?php

/**
 * ===============================================
 * 上传类
 * shuky
 * 2008-04-23 13:47:00
 * ===============================================
 */

class Upload
{

    const FILE_FETCH_ERR = -1;
    const DIR_NOT_EXISTS = -2;
    const CANNOT_UPLOAD = -3;
    const DB_INSERT_ERR = -4;

    protected $_up_path = '';
    protected $_allow_type = array('jpg', 'png', 'gif');

    public function __construct($to_path = '')
    {
        if ($to_path != '') {
            $this->SetPath($to_path);
        }
    }

    //=====================================================================
    // 设置路径
    public function setPath($to_path)
    {
        if (strrchr($to_path, '/') != '/') {
            $to_path .= '/';
        }
        if (!is_dir($to_path)) {
            $ups = explode('/', $to_path);
            $path = $ups[0];
            foreach ($ups as $key=>$up) {
                if ($key && $up) {
                    $path .= '/'. $up;
                }
                if (!is_dir($path)) {
                    mkdir($path);
                }
            }
        }
        $this->_up_path = $to_path;
    }

    public function upOneFile($f_name = 'attach', $to_path = '')
    {
        if (trim($to_path)) {
            $this->SetPath($to_path);
        }
        // 获取上传文件
        $attach = $this->fetchUpload($f_name, 1);
        $return_img = array();
        if (!empty($attach) && !$this->notUploaded($attach)) {
            if (true == ($attach = $this->checkUpload($attach))) {
                $new_file = $this->_up_path . $attach['new_name'] . '.' . $attach['ext'];
                $this->upToPath($attach['tmp_name'], $new_file);
                $info = getimagesize($new_file);
                // 返回的数组
                $return_img['name'] = $attach['name'];
                $return_img['new_name'] = $attach['new_name'] . '.' . $attach['ext'];
                $return_img['ext'] = $attach['ext'];
                $return_img['size'] = $attach['size'];
                $return_img['width'] = $info[0];
                $return_img['height'] = $info[1];
            } else {
                return false;
            }
        }
        return $return_img;
    }
    
    
    /**
     * 上传文件
     * @param string $f_name 上传框name
     * @param string $to_path 路径
     */
    public function upFiles($f_name = 'attach', $to_path = '')
    {
        if (trim($to_path)) {
            $this->setPath($to_path);
        }
        // 获取上传文件
        $attach = $this->fetchUpload($f_name);
        $return_img = array();
        if (!empty($attach)) {
            foreach ($attach as $key => $att) {
                if ($this->notUploaded($att)) {
                    $return_img[$key] = '';
                    continue;
                }
                if (true == ($att = $this->checkUpload($att))) {
                    $new_file = $this->_up_path . $att['new_name'] . '.' . $att['ext'];
                    $this->upToPath($att['tmp_name'], $new_file);
                    $info = getimagesize($new_file);
                    // 返回的数组
                    $return_img[$key]['name'] = $att['name'];
                    $return_img[$key]['new_name'] = $att['new_name'] . '.' . $att['ext'];
                    $return_img[$key]['ext'] = $att['ext'];
                    $return_img[$key]['size'] = $att['size'];
                    $return_img[$key]['width'] = $info[0];
                    $return_img[$key]['height'] = $info[1];
                } else {
                    return false;
                }
            }
        }
        return $return_img;
    }
    
    
    /**
     * 获取上传文件
     * @param string $f_name 对应上传框name
     * @param int $type 1为1个文件，0为多个文件
     */
    protected function fetchUpload($f_name, $type = 0)
    {
        $attachments = array();
        if (trim($f_name) && isset($_FILES[$f_name]) && is_array($_FILES[$f_name])) {
            if ($type == 0) {
                foreach ($_FILES[$f_name] as $key => $var) {
                    foreach ($var as $id => $val) {
                        $attachments[$id][$key] = $val;
                    }
                }
            } else {
                $attachments = $_FILES[$f_name];
            }
        }
        return $attachments;
    }
    
    
    /**
     * 检查处理上传文件获取的相应参数
     * @param type $att
     */
    protected function checkUpload($att)
    {
        $c_att = array(
            'name' => trim($att['name']),
            'ext' => substr(strrchr($att['name'], '.'), 1),
            'type' => $att['type'],
            'tmp_name' => $att['tmp_name'],
            'size' => ceil($att['size'] / 1024),
            'new_name' => substr(md5(time() + mt_rand()), 0, 22),
        );
        if (in_array($c_att['ext'], $this->_allow_type)) {
            return $c_att;
        } else {
            return false;
        }
    }
    
    
    /**
     * 判断文件是否是通过 HTTP POST 上传的
     */
    protected function notUploaded($att)
    {
        if ($att['tmp_name'] == 'none') {
            $att['tmp_name'] = '';
        }
        return ($att['tmp_name'] == '' || $att['name'] == '' || !(is_uploaded_file($att['tmp_name']) || is_uploaded_file(str_replace('\\\\', '\\', $att['tmp_name']))));
    }
    
    
    /**
     * 上传文件
     */
    protected function upToPath($source, $target)
    {
        // 如果一种函数上传失败，用其他函数上传
        if (function_exists('move_uploaded_file') && move_uploaded_file($source, $target)) {
            @chmod($target, 0666);
            return $target;
        } elseif (copy($source, $target)) {
            @chmod($target, 0666);
            return $target;
        } elseif (is_readable($source)) {
            if (true == ($fp = fopen($source, 'rb'))) {
                flock($fp, 2);
                $filedata = fread($fp, filesize($source));
                fclose($fp);
            }
            if (true == ($fp = fopen($target, 'wb'))) {
                flock($fp, 2);
                fwrite($fp, $filedata);
                fclose($fp);
                @chmod($target, 0666);
                return $target;
            } else {
                return false;
            }
        }
    }

}